package com.ssy.lingxi.dataauth.annotation.common;

import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.dataauth.handler.RedisServiceHolder;
import com.ssy.lingxi.dataauth.model.constant.DataAuthConstant;
import com.ssy.lingxi.dataauth.model.dto.DataAuthDto;
import com.ssy.lingxi.dataauth.utils.DataAuthUtil;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 判断是否有数据权限方法参数注解Resolver
 * @author 万宁
 * @version 2.0.0
 * @date 2021-12-30
 */
@Component
public class HasDataAuthResolver implements HandlerMethodArgumentResolver {
    @Resource
    private HttpServletRequest request;

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(HasDataAuth.class);
    }

    @Override
    public Boolean resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        //Step 1:从HttpHeader中，找到当前请求的token、source、userId、Referer（并截取前端Url）
        String token = request.getHeader("token");
        String userId = request.getHeader("userId");
        String source = request.getHeader("source");
        String authUrl = DataAuthUtil.findRequestPath(request.getHeader(DataAuthConstant.HTTP_HEADER_REFERER));

        if(!StringUtils.hasText(authUrl) || !StringUtils.hasText(token) || !StringUtils.hasText(source) || !StringUtils.hasText(userId)) {
            return false;
        }

        //Step 2: 从Redis缓存中读取用户数据权限配置，如果没有数据权限配置，则返回的是Null
        String dataAuthKey = String.format(DataAuthConstant.DATA_AUTH_CACHE_KEY_FORMAT, token, userId, source);
        DataAuthDto dataAuthDto = (DataAuthDto) RedisServiceHolder.redisUtils.hGet(dataAuthKey, authUrl, Constants.REDIS_USER_INDEX);
        return Objects.nonNull(dataAuthDto);
    }
}
